home *** CD-ROM | disk | FTP | other *** search
- //-----------------------------------------------------------------v1.00----//
- // 4D Serial is copyright 1994-1995 by 4D Software / Jeff Jones. You are //
- // given permission to use these routines under the following conditions. //
- // We see how hard it is to get these routines, so I am being nice enough //
- // to allow you to use them *FREE of charge (note the conditions below). //
- // //
- // Conditions: //
- // 1) You must place in your software documentation where to //
- // find our routines, as well as note that you used them. //
- // If you have no documentation, include the 4D Serial LIB //
- // in your archive package, or on disk. //
- // //
- // 2) Send us a free, registered copy of the program you wrote //
- // using these routines. 312-284-2261 is our voice number, //
- // 312-284-7133 is our BBS number. Our Mailing address is //
- // P.O. Box 389051, Chicago, Illinois, 60638. //
- // //
- // 3) If you are using our routines in a commercial software //
- // application, you MUST get in touch of us for WRITTEN //
- // permission of use. (See #2 for address and phone #'s) //
- // * FREE is a term for general use, commercial use my be required to pay //
- // for research time, etc... //
- // //
- // QUESTIONS??? Call our BBS or write. NO VOICE CALLS FOR CODE QUESTIONS! //
- // //
- // ERRORS or CODE REVISIONS: Send them to us via BBS, or call voice. We //
- // will try to help as much as possible. DO NOT DISTRIBUTE 4D SERIAL IN //
- // ANY KIND OF MODIFIED FORM! //
- //--------------------------------------------------------------------------//
-
- //------------------------------------------------------------------//
- // * Compile this program with Test Stack Overflow OFF * //
- //------------------------------------------------------------------//
-
- #ifdef __cplusplus
- #define __CPPARGS ...
- #else
- #define __CPPARGS
- #endif
-
- #include <dos.h>
- #include <string.h>
- #include <alloc.h>
- #include <4dserial.h>
-
- char *SERIAL_OSName[5] = { "Unknown", "DOS", "OS/2", "DESQview", "Windows" };
-
- SERIALINFO SERIAL;
-
- //------------------------------------------------------------------//
- // The following functions are local to 4D SERIAL itself //
- //------------------------------------------------------------------//
-
- void interrupt far (*SERIAL_TimerOldHandler)(__CPPARGS);
- void interrupt far SERIAL_TimerIntHandler(__CPPARGS);
- void SERIAL_TimerInitISR(void);
- void SERIAL_TimerDeInitISR(void);
-
- void interrupt far (*SERIAL_OldHandler)(__CPPARGS);
- void interrupt far SERIAL_IntHandler(__CPPARGS);
- static char SERIAL_CheckInt(void);
- void SERIAL_FIFOInit(void);
- int SERIAL_InitISR(int irqnum);
- void SERIAL_UnInitISR(void);
- void SERIAL_InitBuffer(RING *ring, char *address, int length);
- void SERIAL_PutBuf(RING *ring, char chr);
- int SERIAL_GetBuf(RING *ring, char *chr);
- static char SERIAL_ComBuffers(char create, int inbufsize, int outbufsize);
- void SERIAL_SetCommParams(long baudrate, int parity, int databits, int stopbits);
- int SERIAL_SendChar(char c);
- void SERIAL_SetDTR(char OnOff);
- void SERIAL_SetRTS(char OnOff);
- int SERIAL_CheckRTS(void);
- int SERIAL_CheckCTS(void);
- int SERIAL_CarrierDetect(void);
- void SERIAL_Break(char OnOff);
- int SERIAL_CharReady(void);
-
- int FOSSIL_InitializeDriver(void);
- int FOSSIL_SetPort(long baudrate, int parity, int databits, int stopbits);
- void FOSSIL_HandshakeOn(void);
- void FOSSIL_DeInitializeDriver(void);
- int FOSSIL_SendChar(char c);
- void FOSSIL_SetDTR(char OnOff);
- int FOSSIL_CarrierDetect(void);
- void FOSSIL_Break(char OnOff);
- char FOSSIL_GetChar(void);
- int FOSSIL_CharReady(void);
- void FOSSIL_CheckErrors(void);
- void FOSSIL_PurgeOutBuf(void);
- void FOSSIL_PurgeInBuf(void);
- void FOSSIL_FlushOutBuf(void);
-
- int DIGIBOARD_InitializeDriver(void);
- int DIGIBOARD_SetPort(long baudrate, int parity, int databits, int stopbits);
- void DIGIBOARD_HandshakeOn(void);
- void DIGIBOARD_DeInitializeDriver(void);
- int DIGIBOARD_SendChar(char c);
- void DIGIBOARD_SetDTR(char OnOff);
- int DIGIBOARD_CarrierDetect(void);
- void DIGIBOARD_Break(void);
- char DIGIBOARD_GetChar(void);
- int DIGIBOARD_CharReady(void);
- void DIGIBOARD_CheckErrors(void);
- void DIGIBOARD_PurgeOutBuf(void);
- void DIGIBOARD_PurgeInBuf(void);
- void DIGIBOARD_FlushOutBuf(void);
-
- //------------------------------------------------------------------//
- // The following functions are used by you the programmer //
- //------------------------------------------------------------------//
-
- int SERIAL_OpenPort(char AsyncType, unsigned PortBase, int IRQ, long baudrate, int parity, int databits, int stopbits);
- void SERIAL_ClosePort(void);
- int SERIAL_CheckError(void);
- int SERIAL_TransmitChar(char c);
- void SERIAL_TransmitStr(char *s);
- int SERIAL_ReceiveChar(void);
- int SERIAL_DataReady(void);
- void SERIAL_ToggleDTR(char OnOff);
- void SERIAL_TransmitBreak(void);
- int SERIAL_OnLine(void);
- void SERIAL_PurgeOutBuf(void);
- void SERIAL_PurgeInBuf(void);
- void SERIAL_FlushOutBuf(void);
- void SERIAL_GetOSType(void);
- void SERIAL_GiveSlice(void);
- void SERIAL_TickDelay(long Ticks);
- void SERIAL_SetTimer(int TimerNumber, long Ticks);
- long SERIAL_GetTimer(int TimerNumber);
-
- //------------------------------------------------------------------//
- // END OF HEADER BLOCK - FUNCTIONS ARE NOW LISTED //
- //------------------------------------------------------------------//
-
- static char SERIAL_CheckInt(void) {
-
- unsigned char intreg, chr;
- int i;
-
- intreg = inp(SERIAL.PortBase + 2) | 248; // Identify interrupt //
- // The 248 mask out the upper 5 bits //
-
- if (intreg & 1) return(0); // Nothing pending //
-
- switch(intreg) {
- case 248 : // Modem status change //
- SERIAL.ModemStatus = inp(SERIAL.PortBase + 6);
- return(1);
- case 250 : // Transmitter holding register empty //
- SERIAL.LineStatus = inp(SERIAL.PortBase + 5);
- if (!SERIAL_CarrierDetect() || (SERIAL.ModemStatus & 16)) { // CTS is up before sending a character //
- for (i = 0; (i < SERIAL.MaxSend) && SERIAL.OutRing.Count; i++) {
- SERIAL_GetBuf(&SERIAL.OutRing, &SERIAL.InChar);
- outp(SERIAL.PortBase, SERIAL.InChar);
- }
- }
- return(1);
- case 252 : // RX data available //
- while (inp(SERIAL.PortBase + 5) & 1 /* Data Ready */) {
- chr = inp(SERIAL.PortBase);
- if ((chr == 0x0B) || // Control-K Received //
- (chr == 0x03)) // Control-C Received //
- SERIAL.Abort = chr;
- else
- SERIAL_PutBuf(&SERIAL.InRing, chr);
- }
-
- return(1);
- case 254 : // Line status change //
- SERIAL.LineStatus = inp(SERIAL.PortBase + 5);
- if (SERIAL.LineStatus & 2 /* Overrun Error */)
- SERIAL.Error = SERIAL_OVRRUN_ERROR;
- if (SERIAL.LineStatus & 4 /* Parity Error */)
- SERIAL.Error = SERIAL_PARITY_ERROR;
- if (SERIAL.LineStatus & 8 /* Frame Error */)
- SERIAL.Error = SERIAL_FRAME_ERROR;
- if (SERIAL.LineStatus & 16 /* Break Error */)
- SERIAL.Error = SERIAL_BREAK_ERROR;
- return(1);
- }
- return(0); // Error
-
- }
-
- void interrupt far SERIAL_IntHandler(__CPPARGS) {
-
- enable();
-
- if (SERIAL_CheckInt() == 0) { // No interrupt identifiable //
- if (SERIAL.IRQShared) // Determine is the IRQ is shared or not //
- _chain_intr(SERIAL_OldHandler); // Execute the Old Handler //
- }
- else while(SERIAL_CheckInt()); // Process all interrupt events //
-
- if (SERIAL.IRQ > 7)
- outp(0x00A0, 0x0020); // Check for 2nd PIC //
-
- outp(0x0020, 0x0020); // Send End of Interrupt to 1st PIC //
-
- }
-
- void SERIAL_FIFOInit(void) {
-
- SERIAL.FIFOExists = 0;
- SERIAL.MaxSend = 1;
-
- // If local mode, there's no communication, so no FIFO //
- if (SERIAL.Type == SERIAL_LOCAL) return;
-
- // See if UART is an 8250 (no scratch register) //
- outp(SERIAL.PortBase + 7 /* Scratch Register */, 0x55);
- if (inp(SERIAL.PortBase + 7 /* Scratch Register */) != 0x55)
- return; // No scratch register, it's an 8250 //
-
- // See if the UART has a FIFO buffer //
- outp(SERIAL.PortBase + 2, 0x0F);
-
- if (inp(SERIAL.PortBase + 2)) return;
-
- SERIAL.FIFOExists = 1;
- SERIAL.MaxSend = 8;
-
- outp(SERIAL.PortBase + 2, 1 | 2 | 4 | 64) ; // 8 byte trigger level //
-
- }
-
- int SERIAL_InitISR(int irqnum) {
-
- unsigned char picmask, oldvalue;
-
- SERIAL.IRQ = irqnum;
-
- SERIAL_OldHandler = _dos_getvect(irqnum + 8);
-
- _dos_setvect(irqnum + 8, SERIAL_IntHandler);
-
- // Setup Modem Control Register's bits //
-
- outp(SERIAL.PortBase + 4 /* Modem Control */, 0x0001 | 0x0002 | 0x0004 | 0x0008);
-
- picmask = 1 << (SERIAL.IRQ % 8);
-
- disable();
-
- oldvalue = inp(((SERIAL.IRQ > 7) ? 0x00A0 : 0x0020) + 1); // Read PIC's interrupt enable register //
- outp(((SERIAL.IRQ > 7) ? 0x00A0 : 0x0020) + 1, oldvalue & !picmask);
-
- enable();
-
- SERIAL.IRQShared = !(oldvalue & picmask);
-
- outp(SERIAL.PortBase + 1, 0); // Disable UART interrupts //
-
- SERIAL_FIFOInit();
-
- // Read UART registers to clear them //
- SERIAL.ModemStatus = inp(SERIAL.PortBase + 6);
- SERIAL.LineStatus = inp(SERIAL.PortBase + 5);
- inp(SERIAL.PortBase); // Read any pending chars //
- inp(SERIAL.PortBase + 2); // to clear the interrupt //
- // identification reg //
-
- outp(SERIAL.PortBase + 1, 1 | 2 | 4 | 8); // Enable UART interrupts //
-
- outp((SERIAL.IRQ > 7) ? 0x00A0 : 0x0020, 0x0020); // Reset the PIC //
-
- return(1);
-
- }
-
- void SERIAL_UnInitISR(void) {
-
- if (SERIAL.FIFOExists)
- outp(SERIAL.PortBase + 2, 0x00); //Turn off the FIFO, if ON //
-
- outp(SERIAL.PortBase + 1, 0x00); // Disable UART interrupts //
- _dos_setvect(SERIAL.IRQ + 8, SERIAL_OldHandler);
-
- }
-
- void SERIAL_InitBuffer(RING *ring, char *address, int length) {
-
- // Initialize the buffer values //
- ring->Count = 0;
- ring->Start = 0;
- ring->Cnext = 0;
- ring->Buffer = address;
- ring->Size = length;
- }
-
- void SERIAL_PutBuf(RING *ring, char chr) {
-
- // Puts a character into the rotating buffer (ring buffer) //
- ring->Buffer[ring->Cnext++] = chr;
-
- if (ring->Count++ >= ring->Size) { // Overflow Condition? //
- ring->Count--;
-
- if (ring->Start++ >= ring->Size) // Move the starting point //
- ring->Start -= ring->Size;
- }
-
- // Check if we need to wrap to the the beginning of the buffer again //
- if (ring->Cnext >= ring->Size) ring->Cnext -= ring->Size;
-
- if ((!SERIAL.InputHS)&&(SERIAL.InRing.Size-SERIAL.InRing.Count < 2)) {
- SERIAL.InputHS = 1;
- SERIAL_SetRTS(0);
- }
- }
-
- int SERIAL_GetBuf(RING *ring, char *chr) {
-
- // Retrieve a character from our ring buffer //
- if (ring->Count <= 0) return(0); // Buffer empty - nothing there //
-
- *chr = (char) ring->Buffer[ring->Start++];
- ring->Count--; // Update amount of retrievable characters //
-
- if (ring->Start >= ring->Size) ring->Start -= ring->Size;
-
- if ((SERIAL.InputHS)&&(SERIAL.InRing.Count < (SERIAL.InRing.Size*.8))) {
- SERIAL.InputHS = 0;
- SERIAL_SetRTS(1);
- }
-
- return(1);
- }
-
- static char SERIAL_ComBuffers(char create, int inbufsize, int outbufsize) {
-
- static char *outbuf;
- static char *inbuf;
- static char cbmade = 0;
-
- if (create) { // Create our buffer //
- if (cbmade) return(1);
- if ((outbuf = (char *) malloc(outbufsize)) == NULL) return(0);
-
- if ((inbuf = (char *) malloc(inbufsize)) == NULL) {
- free(outbuf);
- return(0);
- }
-
- SERIAL_InitBuffer(&SERIAL.OutRing, outbuf, outbufsize);
- SERIAL_InitBuffer(&SERIAL.InRing, inbuf, inbufsize);
- cbmade = 1;
- return(1);
- }
-
- else { // Kill a buffer for closing purposes //
- if (cbmade) {
- free(inbuf);
- free(outbuf);
- cbmade = 0;
- }
- return(0);
- }
- }
-
- void SERIAL_SetCommParams(long baudrate, int parity, int databits, int stopbits) {
-
- unsigned int divisor;
- unsigned char lsb, msb;
- unsigned char parambyte;
-
- divisor = 115200l / baudrate;
- msb = divisor >> 8;
- lsb = (divisor << 8) >> 8;
-
- outp(SERIAL.PortBase + 3, 128 /* DLAB */); // Enable access to the divisor //
- // latches by setting the divisor //
- // latch access bit int the Line //
- // Control Register //
-
- outp(SERIAL.PortBase, lsb); // Least Significant bit of divisor //
- outp(SERIAL.PortBase + 1, msb); // Most significant bit //
-
- parambyte = databits - 5; // Sets Bits 1 + 2 //
-
- if (stopbits == 2) parambyte |= 4; // LCR stop bits setting //
-
- switch(parity) {
- case 'O' : // Odd Parity //
- case 'o' : parambyte |= 8; // LCR Parity Enable bit //
- break;
- case 'E' : // Even Parity //
- case 'e' : parambyte |= 8; // LCR Parity Enable bit //
- parambyte |= 16; // LCR Parity Select bit //
- break;
- default : // No parity is the default if not an 'O' or 'E' //
- break;
- }
-
- outp(SERIAL.PortBase + 3, parambyte);
-
- }
-
- int SERIAL_SendChar(char c) {
-
- if (SERIAL.OutRing.Count || !(inp(SERIAL.PortBase + 5) & 32 /* THRE */)) {
- if (SERIAL.OutRing.Count >= SERIAL.OutRing.Size)
- return(1); // Buffer is Full, don't add the new char //
- SERIAL_PutBuf(&SERIAL.OutRing, c); // Add char to output buffer //
- }
- else
- outp(SERIAL.PortBase, c);
-
- return(0);
- }
-
- void SERIAL_SetDTR(char OnOff) {
-
- int r;
-
- r = inp(SERIAL.PortBase + 4 /* Modem Control */);
-
- if (OnOff)
- outp(SERIAL.PortBase + 4 /* Modem Control */, r | 0x0001);
- else
- outp(SERIAL.PortBase + 4 /* Modem Control */, r & (~0x0001));
- }
-
- void SERIAL_SetRTS(char OnOff) {
-
- int r;
-
- r = inp(SERIAL.PortBase + 4 /* Modem Control */);
-
- if (OnOff)
- outp(SERIAL.PortBase + 4 /* Modem Control */, r | 0x0002);
- else
- outp(SERIAL.PortBase + 4 /* Modem Control */, r & (~0x0002));
- }
-
- int SERIAL_CheckRTS(void) { // Returns True is RTS is up //
-
- return(inp(SERIAL.PortBase + 4 /* Modem Control */) & 0x0002);
-
- }
-
- int SERIAL_CheckCTS(void) { // Returns True is CTS is up //
-
- return(inp(SERIAL.PortBase + 6 /* Modem Control */) & 0x0010);
-
- }
-
- int SERIAL_CarrierDetect(void) {
-
- if (inp(SERIAL.PortBase + 6) & 128) return(1);
-
- return(0);
- }
-
- void SERIAL_Break(char OnOff) {
-
- int r;
-
- r = inp(SERIAL.PortBase + 3 /* Line Control */);
-
- if (OnOff)
- outp(SERIAL.PortBase + 3 /* Line Control */, r | 0x0040);
- else
- outp(SERIAL.PortBase + 3 /* Line Control */, r & (~0x0040));
- }
-
- int SERIAL_CharReady(void) {
-
- if (SERIAL.InRing.Count > 0) return(1); // Buffer has a char in it //
-
- return(0);
- }
-
- int FOSSIL_InitializeDriver(void) {
-
- union REGS regs;
- struct SREGS sregs;
-
- regs.h.ah = 0x04;
- regs.x.dx = SERIAL.PortBase;
- int86x(0x14,®s, ®s, &sregs);
- if (regs.x.ax != 0x1954) return(1);
-
- return(0);
- }
-
- int FOSSIL_SetPort(long baudrate, int parity, int databits, int stopbits) {
-
- union REGS regs;
- int Set = 0;
-
- switch(baudrate) {
- case 300 : Set = 0x40; break; // 010 (set 7th logical bit to on) //
- case 600 : Set = 0x60; break; // 011 //
- case 1200 : Set = 0x80; break; // 100 //
- case 2400 : Set = 0xA0; break; // 101 //
- case 4800 : Set = 0xC0; break; // 110 //
- case 9600 : Set = 0xE0; break; // 111 //
- case 19200 : Set = 0x00; break; // 000 //
- case 38400 : Set = 0x02; break; // 001 //
- default : return(1);
- }
-
- switch(parity) {
- case 'O' :
- case 'o' : Set |= 0x08; break; // 01 (4th logical bit to on) //
- case 'E' :
- case 'e' : Set |= 0x18; break; // 11 (5th and 4th bits to on) //
- default : Set |= 0x00; break; // 00 //
- }
-
- switch(stopbits) {
- case 1 : Set |= 0x00; break; // 0 (3rd logical bit to off) //
- default : Set |= 0x04; break; // 1 //
- }
-
- switch(databits) {
- case 5 : Set |= 0x00; break; // 00 (bits 2 and 1 off) //
- case 6 : Set |= 0x01; break; // 01 //
- case 7 : Set |= 0x02; break; // 10 //
- default : Set |= 0x03; break; // 11 //
- }
-
- regs.h.ah = 0x00;
- regs.h.al = Set;
- regs.x.dx = SERIAL.PortBase;
- int86(0x14,®s, ®s);
-
- return(0);
- }
-
- void FOSSIL_Break(char OnOff) {
-
- union REGS regs;
-
- regs.h.ah = 0x1A; // Transmit, no wait //
- regs.x.dx = SERIAL.PortBase;
- if (OnOff)
- regs.h.al = 0x01; // On //
- else
- regs.h.al = 0x00; // Off //
- int86(0x14,®s, ®s);
- }
-
- int FOSSIL_CarrierDetect(void) {
-
- union REGS regs;
-
- regs.h.ah = 0x03; // Request Status //
- regs.x.dx = SERIAL.PortBase;
- int86(0x14,®s, ®s);
- if (regs.h.al & 128) return(1);
- return(0);
- }
-
- void FOSSIL_SetDTR(char OnOff) {
-
- union REGS regs;
-
- regs.h.ah = 0x06;
- regs.x.dx = SERIAL.PortBase;
- if (OnOff)
- regs.h.al = 0x01; // Raise //
- else
- regs.h.al = 0x00; // Lower //
- int86(0x14,®s, ®s);
- }
-
- void FOSSIL_HandshakeOn(void) {
-
- union REGS regs;
-
- regs.h.ah = 0x0F; // Transmit, no wait //
- regs.x.dx = SERIAL.PortBase;
- regs.h.al = 242;
- int86(0x14,®s, ®s);
- }
-
- char FOSSIL_GetChar(void) {
-
- union REGS regs;
-
- regs.h.ah = 0x02; // Receive, with wait //
- regs.x.dx = SERIAL.PortBase;
- int86(0x14,®s, ®s);
-
- return(regs.h.al);
- }
-
- int FOSSIL_CharReady(void) {
-
- union REGS regs;
-
- regs.h.ah = 0x0C; // `PEEK' style char read w/Status of Availability //
- regs.x.dx = SERIAL.PortBase;
- int86(0x14,®s, ®s);
- if (regs.x.ax == 0xFFFF) return(0);
-
- if ((regs.h.al == 0x0B) || // Control-K Received //
- (regs.h.al == 0x03)) { // Control-C Received //
- FOSSIL_GetChar(); // Remove NOW unwanted character //
- SERIAL.Abort = regs.h.al;
- }
- else return(1);
-
- return(0);
- }
-
- int FOSSIL_SendChar(char c) {
-
- union REGS regs;
-
- regs.h.ah = 0x0B; // Transmit, no wait //
- regs.x.dx = SERIAL.PortBase;
- regs.h.al = c;
- int86(0x14,®s, ®s);
- if (regs.x.ax == 0x0000) return(1);
-
- return(0);
- }
-
- void FOSSIL_CheckErrors(void) {
-
- union REGS regs;
-
- regs.h.ah = 0x03;
- regs.x.dx = SERIAL.PortBase;
- int86(0x14,®s, ®s);
- if (regs.h.ah & 2 /* Overrun Error */)
- SERIAL.Error = SERIAL_OVRRUN_ERROR;
- }
-
- void FOSSIL_PurgeOutBuf(void) {
-
- union REGS regs;
-
- regs.h.ah = 0x09;
- regs.x.dx = SERIAL.PortBase;
- int86(0x14,®s, ®s);
- }
-
- void FOSSIL_PurgeInBuf(void) {
-
- union REGS regs;
-
- regs.h.ah = 0x0A;
- regs.x.dx = SERIAL.PortBase;
- int86(0x14,®s, ®s);
- }
-
- void FOSSIL_FlushOutBuf(void) {
-
- union REGS regs;
-
- regs.h.ah = 0x08;
- regs.x.dx = SERIAL.PortBase;
- int86(0x14,®s, ®s);
- }
-
- void FOSSIL_DeInitializeDriver(void) {
-
- union REGS regs;
-
- regs.h.ah = 0x05;
- regs.x.dx = SERIAL.PortBase;
- int86(0x14,®s, ®s);
- }
-
- int SERIAL_OpenPort(char AsyncType, unsigned PortBase, int IRQ, long baudrate, int parity, int databits, int stopbits) {
-
- memset(&SERIAL,0,sizeof(SERIALINFO)); // Set all data members to 0 //
- SERIAL.PortBase = PortBase;
- SERIAL.Type = AsyncType;
-
- switch(AsyncType) {
- case SERIAL_LOCAL :
- break;
-
- case SERIAL_ASYNC :
- if ((IRQ < 2) || (IRQ > 15) || (!PortBase)) return(1);
-
- SERIAL_SetCommParams(baudrate,parity,databits,stopbits);
- if (!SERIAL_ComBuffers(1, 4096, 2048)) return(2); // 4K input buffer, 2K output buffer
- SERIAL_InitISR(IRQ);
-
- break;
-
- case SERIAL_FOSSIL :
- if ((SERIAL.PortBase > 64)||(SERIAL.PortBase < 0)) return(3);
- if (FOSSIL_InitializeDriver()) return(4);
- if (FOSSIL_SetPort(baudrate,parity,databits,stopbits)) {
- FOSSIL_DeInitializeDriver();
- return(5);
- }
- FOSSIL_HandshakeOn();
-
- break;
-
- case SERIAL_DIGIBOARD :
- if ((SERIAL.PortBase > 64)||(SERIAL.PortBase < 0)) return(3);
- if (DIGIBOARD_InitializeDriver()) return(4);
- if (DIGIBOARD_SetPort(baudrate,parity,databits,stopbits)) {
- DIGIBOARD_DeInitializeDriver();
- return(5);
- }
- DIGIBOARD_HandshakeOn();
-
- break;
-
- default :
- return(2);
- }
-
- SERIAL_TimerInitISR();
- return(0);
- }
-
- void SERIAL_ClosePort(void) {
-
- SERIAL_TimerDeInitISR();
-
- switch(SERIAL.Type) {
- case SERIAL_LOCAL :
- break;
-
- case SERIAL_ASYNC :
- SERIAL_UnInitISR(); // Reset Interrupt Vector to original //
- SERIAL_ComBuffers(0, 4096, 2048); // De-Init Ring Buffers //
- break;
-
- case SERIAL_FOSSIL :
- FOSSIL_DeInitializeDriver();
- break;
-
- case SERIAL_DIGIBOARD :
- DIGIBOARD_DeInitializeDriver();
- break;
-
- default :
- break;
- }
- }
-
- int SERIAL_TransmitChar(char c) {
-
- switch(SERIAL.Type) {
- case SERIAL_LOCAL : return(0);
- case SERIAL_ASYNC : return(SERIAL_SendChar(c));
- case SERIAL_FOSSIL : return(FOSSIL_SendChar(c));
- case SERIAL_DIGIBOARD : return(DIGIBOARD_SendChar(c));
- }
- return(0);
- }
-
- int SERIAL_DataReady(void) {
-
- switch(SERIAL.Type) {
- case SERIAL_LOCAL : return(0);
- case SERIAL_ASYNC : return(SERIAL_CharReady());
- case SERIAL_FOSSIL : return(FOSSIL_CharReady());
- case SERIAL_DIGIBOARD : return(DIGIBOARD_CharReady());
- }
- return(0);
- }
-
- void SERIAL_ToggleDTR(char OnOff) {
-
- switch(SERIAL.Type) {
- case SERIAL_LOCAL : return;
- case SERIAL_ASYNC : SERIAL_SetDTR(OnOff); break;
- case SERIAL_FOSSIL : FOSSIL_SetDTR(OnOff); break;
- case SERIAL_DIGIBOARD : DIGIBOARD_SetDTR(OnOff); break;
- }
- }
-
- int SERIAL_OnLine(void) {
-
- switch(SERIAL.Type) {
- case SERIAL_LOCAL : return(1);
- case SERIAL_ASYNC : return(SERIAL_CarrierDetect());
- case SERIAL_FOSSIL : return(FOSSIL_CarrierDetect());
- case SERIAL_DIGIBOARD : return(DIGIBOARD_CarrierDetect());
- }
- return(0);
- }
-
- int SERIAL_CheckError(void) {
-
- switch(SERIAL.Type) {
- case SERIAL_LOCAL : break;
- case SERIAL_ASYNC : break;
- case SERIAL_FOSSIL : FOSSIL_CheckErrors(); break;
- case SERIAL_DIGIBOARD : DIGIBOARD_CheckErrors(); break;
- }
- return(SERIAL.Error);
- }
-
- int SERIAL_ReceiveChar(void) { // No WAIT function //
-
- char c;
-
- switch(SERIAL.Type) {
- case SERIAL_LOCAL : break;
-
- case SERIAL_ASYNC : if (SERIAL_GetBuf(&SERIAL.InRing, &c))
- return(c);
- break;
-
- case SERIAL_FOSSIL : if (FOSSIL_CharReady())
- return(FOSSIL_GetChar());
- break;
-
- case SERIAL_DIGIBOARD : if (DIGIBOARD_CharReady())
- return(DIGIBOARD_GetChar());
- break;
- }
- return(0);
- }
-
- void SERIAL_TransmitStr(char *s) {
-
- switch(SERIAL.Type) {
- case SERIAL_LOCAL : break;
- case SERIAL_ASYNC : while(*s) SERIAL_SendChar(*s++); break;
- case SERIAL_FOSSIL : while(*s) FOSSIL_SendChar(*s++); break;
- case SERIAL_DIGIBOARD : while(*s) DIGIBOARD_SendChar(*s++); break;
- }
- return;
- }
-
- void SERIAL_PurgeOutBuf(void) {
-
- switch(SERIAL.Type) {
- case SERIAL_LOCAL : break;
-
- case SERIAL_ASYNC : // RE-Initialize the buffer values //
- SERIAL.OutRing.Count = 0;
- SERIAL.OutRing.Start = 0;
- SERIAL.OutRing.Cnext = 0;
- break;
-
- case SERIAL_FOSSIL : FOSSIL_PurgeOutBuf(); break;
-
- case SERIAL_DIGIBOARD : DIGIBOARD_PurgeOutBuf(); break;
- }
- return;
- }
-
- void SERIAL_PurgeInBuf(void) {
-
- switch(SERIAL.Type) {
- case SERIAL_LOCAL : break;
-
- case SERIAL_ASYNC : // RE-Initialize the buffer values //
- SERIAL.InRing.Count = 0;
- SERIAL.InRing.Start = 0;
- SERIAL.InRing.Cnext = 0;
- break;
-
- case SERIAL_FOSSIL : FOSSIL_PurgeInBuf(); break;
-
- case SERIAL_DIGIBOARD : DIGIBOARD_PurgeInBuf(); break;
- }
- return;
- }
-
- void SERIAL_FlushOutBuf(void) {
-
- switch(SERIAL.Type) {
- case SERIAL_LOCAL : break;
-
- case SERIAL_ASYNC : while(SERIAL_CarrierDetect() && SERIAL.OutRing.Count);
- break;
-
- case SERIAL_FOSSIL : FOSSIL_FlushOutBuf(); break;
-
- case SERIAL_DIGIBOARD : DIGIBOARD_FlushOutBuf(); break;
- }
- return;
- }
-
- void SERIAL_TransmitBreak(void) {
-
- // The 5 ticks for delay we use is slightly more than 250 ms; It's as //
- // close as we can get while giving up time slices. //
-
- switch(SERIAL.Type) {
- case SERIAL_LOCAL : break;
-
- case SERIAL_ASYNC : SERIAL_Break(1);
- SERIAL_TickDelay(5);
- SERIAL_Break(0);
- break;
-
- case SERIAL_FOSSIL : FOSSIL_Break(1);
- SERIAL_TickDelay(5);
- FOSSIL_Break(0);
- break;
-
- case SERIAL_DIGIBOARD : DIGIBOARD_Break(); break;
- }
- return;
- }
-
- int DIGIBOARD_InitializeDriver(void) {
-
- union REGS regs;
- struct SREGS sregs;
-
- regs.h.ah = 0xF4;
- regs.h.al = 0x08;
- regs.x.dx = SERIAL.PortBase;
- int86(0x14,®s, ®s);
- if (regs.x.ax != 0x0000) return(1);
-
- regs.h.ah = 0x0D; // set ah = 0Dh
- regs.h.al = 0x00; // To clear it...
- regs.x.dx = SERIAL.PortBase; // set channel number
- int86x(0x14,®s,®s,&sregs); // make INT 14h call
-
- SERIAL.DataReady =
- (unsigned char far *)MK_FP(sregs.es,regs.x.bx); // far pointer to flag
-
- return(0);
- }
-
- int DIGIBOARD_SetPort(long baudrate, int parity, int databits, int stopbits) {
-
- union REGS regs;
-
- switch(baudrate) {
- case 50 : regs.h.cl = 0x0D; break;
- case 75 : regs.h.cl = 0x0E; break;
- case 110 : regs.h.cl = 0x00; break;
- case 134 : regs.h.cl = 0x0F; break;
- case 150 : regs.h.cl = 0x01; break;
- case 200 : regs.h.cl = 0x10; break;
- case 300 : regs.h.cl = 0x02; break;
- case 600 : regs.h.cl = 0x03; break;
- case 1200 : regs.h.cl = 0x04; break;
- case 1800 : regs.h.cl = 0x11; break;
- case 2400 : regs.h.cl = 0x05; break;
- case 4800 : regs.h.cl = 0x06; break;
- case 9600 : regs.h.cl = 0x07; break;
- case 19200 : regs.h.cl = 0x08; break;
- case 38400 : regs.h.cl = 0x09; break;
- case 57600 : regs.h.cl = 0x0A; break;
- case 76800 : regs.h.cl = 0x0B; break;
- case 115200 : regs.h.cl = 0x0C; break;
- default : return(1);
- }
-
- switch(parity) {
- case 'O' :
- case 'o' : regs.h.bh = 0x01; break;
- case 'E' :
- case 'e' : regs.h.bh = 0x02; break;
- default : regs.h.bh = 0x00; break; // None //
- }
-
- switch(stopbits) {
- case 1 : regs.h.bl = 0x00; break; // 1 Stop Bit //
- default : regs.h.bl = 0x01; break; // Default to two //
- }
-
- switch(databits) {
- case 5 : regs.h.ch = 0x00; break;
- case 6 : regs.h.ch = 0x01; break;
- case 7 : regs.h.ch = 0x02; break;
- default : regs.h.ch = 0x03; break; // Default 8 bits //
- }
-
- regs.h.ah = 0x04;
- regs.h.al = 0x00;
- regs.x.dx = SERIAL.PortBase;
- int86(0x14,®s, ®s);
-
- return(0);
- }
-
- void DIGIBOARD_SetDTR(char OnOff) {
-
- union REGS regs;
-
- regs.h.ah = 0x05;
- regs.h.al = 0x00; // Read //
- regs.x.dx = SERIAL.PortBase;
- int86(0x14,®s, ®s);
-
- regs.h.al = 0x01; // Write //
- if (OnOff)
- regs.h.bl |= 0x01; // Raise //
- else
- regs.h.bl &= ~0x01; // Lower //
- int86(0x14,®s, ®s);
- }
-
- int DIGIBOARD_CarrierDetect(void) {
-
- union REGS regs;
-
- regs.h.ah = 0x03; // Request Status //
- regs.x.dx = SERIAL.PortBase;
- int86(0x14,®s, ®s);
- if (regs.h.al & 128) return(1);
- return(0);
- }
-
- void DIGIBOARD_HandshakeOn(void) {
-
- union REGS regs;
-
- regs.h.ah = 0x1E; // Transmit, no wait //
- regs.x.dx = SERIAL.PortBase;
- regs.h.bh = 0x00;
- regs.h.bl = 0x0A;
- int86(0x14,®s, ®s);
- }
-
- void DIGIBOARD_Break(void) {
-
- union REGS regs;
-
- regs.h.ah = 0x07; // Transmit, no wait //
- regs.h.al = 0x00;
- regs.x.dx = SERIAL.PortBase;
- int86(0x14,®s, ®s);
- }
-
- int DIGIBOARD_CharReady(void) {
-
- union REGS regs;
-
- if (*SERIAL.DataReady != 0xFF) return(0); // No char ready //
-
- regs.h.ah = 0x14; // `PEEK' style char read //
- regs.x.dx = SERIAL.PortBase;
- int86(0x14,®s, ®s);
-
- if ((regs.h.al == 0x0B) || // Control-K Received //
- (regs.h.al == 0x03)) { // Control-C Received //
- DIGIBOARD_GetChar(); // Remove NOW unwanted character //
- SERIAL.Abort = regs.h.al;
- }
- else return(1);
-
- return(0);
- }
-
- void DIGIBOARD_CheckErrors(void) {
-
- union REGS regs;
-
- regs.h.ah = 0x08; // Alternate status check //
- regs.x.dx = SERIAL.PortBase;
- int86(0x14,®s, ®s);
-
- if (regs.h.ah & 2 /* Overrun Error */)
- SERIAL.Error = SERIAL_OVRRUN_ERROR;
- if (regs.h.ah & 4 /* Parity Error */)
- SERIAL.Error = SERIAL_PARITY_ERROR;
- if (regs.h.ah & 8 /* Frame Error */)
- SERIAL.Error = SERIAL_FRAME_ERROR;
- if (regs.h.ah & 16 /* Break Error */)
- SERIAL.Error = SERIAL_BREAK_ERROR;
- }
-
- char DIGIBOARD_GetChar(void) {
-
- union REGS regs;
-
- do {
- regs.h.ah = 0x02; // Receive, with 2 second wait //
- regs.x.dx = SERIAL.PortBase;
- int86(0x14,®s, ®s);
- } while (regs.h.ah & 128); // Make this a WAIT style function, like FOSSIL
-
- return(regs.h.al);
- }
-
- int DIGIBOARD_SendChar(char c) {
-
- union REGS regs;
-
- regs.h.ah = 0x01; // Transmit, no wait //
- regs.x.dx = SERIAL.PortBase;
- regs.h.al = c;
- int86(0x14,®s, ®s);
- if (regs.h.ah & 128) return(1); // Buffer is full - Char not sent! //
-
- return(0); // All's well in the transmit or 'c' //
- }
-
- void DIGIBOARD_PurgeOutBuf(void) {
-
- union REGS regs;
-
- regs.h.ah = 0x11; // FLUSH - not PURGE, as DIGI Driver has no purge interrupt //
- regs.x.dx = SERIAL.PortBase;
- int86(0x14,®s, ®s);
- }
-
- void DIGIBOARD_FlushOutBuf(void) {
-
- union REGS regs;
-
- regs.h.ah = 0x11;
- regs.x.dx = SERIAL.PortBase;
- int86(0x14,®s, ®s);
- }
-
- void DIGIBOARD_PurgeInBuf(void) {
-
- union REGS regs;
-
- while(DIGIBOARD_CharReady()) {
- regs.h.ah = 0xFC;
- regs.x.dx = SERIAL.PortBase;
- int86(0x14,®s, ®s);
- }
- }
-
- void DIGIBOARD_DeInitializeDriver(void) {
-
- // Nothing to do here.... But, I'll keep the function BLANK
- // here for future ease of expansion in the DIGI drivers...
-
- }
-
- void SERIAL_GetOSType(void) {
-
- union REGS t_regs;
- int ostype, maj, min;
-
- ostype = 0;
-
- // test for DOS or OS/2 //
-
- if (_osmajor < 20)
- ostype = ostype | 0x01; // DOS
- else
- ostype = ostype | 0x02; // OS2
-
- // test for Windows //
-
- t_regs.x.ax = 0x1600 ;
- int86(0x2F, &t_regs, &t_regs);
-
- if (t_regs.h.al != 0x00)
- ostype = ostype | 0x08; // Windows
-
- // Test for DESQview //
-
- t_regs.x.cx = 0x4445;
- t_regs.x.dx = 0x5351;
- t_regs.x.ax = 0x2B01;
-
- intdos(&t_regs, &t_regs);
- if (t_regs.h.al != 0xFF)
- ostype = ostype | 0x04; // DV
-
- if (ostype & 0x01)
- SERIAL.OSType = 1; // DOS
-
- if (ostype & 0x08)
- SERIAL.OSType = 4; // Windows
-
- if (ostype & 0x04)
- SERIAL.OSType = 3; // DV
-
- if (ostype & 0x02)
- SERIAL.OSType = 2; // OS2
-
- return;
- }
-
- void SERIAL_GiveSlice(void) {
-
- union REGS t_regs;
-
- if (!SERIAL.OSType) SERIAL_GetOSType();
-
- switch (SERIAL.OSType) {
- case 1 : // DOS
- case 4 : // Windows
- t_regs.x.ax = 0x1680;
- int86(0x2F,&t_regs,&t_regs);
- break;
-
- case 2 : // OS2
- int86(0x28,&t_regs,&t_regs);
- break;
-
- case 3 : // DV
- t_regs.x.ax = 0x1000;
- int86(0x15,&t_regs,&t_regs);
- break;
- }
- }
-
- void interrupt far SERIAL_TimerIntHandler(__CPPARGS) {
-
- register int i = 0;
-
- while(i < 10) SERIAL.Timers[i++]--;
-
- // Execute the Old Handler in case it's chained from another program //
- _chain_intr(SERIAL_TimerOldHandler);
-
- return;
- }
-
- void SERIAL_TimerInitISR(void) {
-
- SERIAL_TimerOldHandler = _dos_getvect(0x1C);
-
- _dos_setvect(0x1C, SERIAL_TimerIntHandler);
- }
-
- void SERIAL_TimerDeInitISR(void) {
-
- _dos_setvect(0x1C, SERIAL_TimerOldHandler); // Reset the interrupt vector upon exit
- }
-
- void SERIAL_SetTimer(int TimerNumber, long Ticks) {
-
- if ((TimerNumber < 0) || (TimerNumber > 9)) return;
-
- SERIAL.Timers[TimerNumber] = Ticks;
- }
-
- long SERIAL_GetTimer(int TimerNumber) {
-
- if ((TimerNumber < 0) || (TimerNumber > 9)) return(-999999999L);
-
- return(SERIAL.Timers[TimerNumber]);
- }
-
- void SERIAL_TickDelay(long Ticks) {
-
- SERIAL_SetTimer(9,Ticks);
- while (SERIAL_GetTimer(9) > 0)
- SERIAL_GiveSlice();
- }